﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TCPAssistant
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private UdpClient Udp_Client = null;
        private IPEndPoint IP_EP = null;
        private Thread Td_UdpReceive;

        private TcpClient Client;
        private Thread Td_Client;

        private Thread Td_Listen;
        private Thread Td_Seriver;
        TcpListener listener;
        private bool m_bListening = false;

        private void Form1_Load(object sender, EventArgs e)
        {
            textBox_IP.Text = ForchLocalIP();
        }
        private string ForchLocalIP()
        {
            string IP = null;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    IP = _IPAddress.ToString();
                }
            }
            return IP;
        }
        int Mode = 0;
        private void comboBox_TcpType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox_TcpType.Text == "UDP")
            {
                Mode = 1;
                label2.Text = "目标IP地址";
                label3.Text = "本地端口";
                textBox_LocalPort.Enabled = true;
                textBox_TargetPort.Enabled = true;
            }
            if (comboBox_TcpType.Text == "TCP Clinet")
            {
                Mode = 2;
                label2.Text = "目标IP地址";
                label3.Text = "本地端口";
                textBox_LocalPort.Enabled = false;
                textBox_TargetPort.Enabled = true;
            }
            if (comboBox_TcpType.Text == "TCP Seriver")
            {
                Mode = 3;
                label2.Text = "服务器IP地址";
                label3.Text = "服务器端口";
                textBox_LocalPort.Enabled = true;
                textBox_TargetPort.Enabled = false;
            }
        }
        private void btn_Connect_Click(object sender, EventArgs e)
        {
            if (btn_Connect.Text == "连接")
            {
                btn_Connect.Text = "断开";
                comboBox_TcpType.Enabled = false;
                textBox_IP.Enabled = false;
                textBox_LocalPort.Enabled = false;
                textBox_TargetPort.Enabled = false;
                if (Mode == 1)
                {
                    UDPConnect(textBox_IP.Text, textBox_TargetPort.Text);
                }
                else if (Mode == 2)
                {
                    ClientConnect(textBox_IP.Text, textBox_TargetPort.Text);
                }
                else if (Mode == 3)
                {
                    SeriverConnect(textBox_IP.Text, textBox_LocalPort.Text);
                }
                else
                {
                    btn_Connect.Text = "连接";
                    comboBox_TcpType.Enabled = true;
                    textBox_IP.Enabled = true;
                    textBox_LocalPort.Enabled = true;
                    textBox_TargetPort.Enabled = true;
                    MessageBox.Show("请选择协议类型");
                }
            }
            else if (btn_Connect.Text == "断开")
            {
                if (Mode == 1)
                {
                    textBox_LocalPort.Enabled = true;
                    textBox_TargetPort.Enabled = true;
                    if (Td_UdpReceive.IsAlive)
                        Td_UdpReceive.Abort();
                    Udp_Client.Close();
                }
                else if (Mode == 2)
                {
                    textBox_LocalPort.Enabled = false;
                    textBox_TargetPort.Enabled = true;
                    ns.Close();
                    if (Td_Client.IsAlive)
                        Td_Client.Abort();
                    if (Client.Connected)
                        Client.Close();
                }
                else if (Mode == 3)
                {
                    textBox_LocalPort.Enabled = true;
                    textBox_TargetPort.Enabled = false;
                    if (Td_Seriver.IsAlive)
                        Td_Seriver.Abort();
                    listener.Stop();
                    if (Td_Listen.IsAlive)
                        Td_Listen.Abort();
                }
                btn_Connect.Text = "连接";
                comboBox_TcpType.Enabled = true;
                textBox_IP.Enabled = true;
                textBox_LocalPort.Enabled = true;
            }
        }
        private void UDPConnect(string ip, string port)
        {
            try
            {
                Udp_Client = new UdpClient(int.Parse(textBox_LocalPort.Text));
                Udp_Client.Connect(ip, int.Parse(port));
                IP_EP = new IPEndPoint(IPAddress.Parse(ip), int.Parse(port));
                Td_UdpReceive = new Thread(UdpReceiveMsg);
                Td_UdpReceive.Start();
                Tips.Text = "连接成功";
            }
            catch (Exception ex)
            {
                Tips.Text = "未连接";
                MessageBox.Show(ex.Message);
            }

        }
        private void UdpReceiveMsg(object obj)
        {
            while (true)
            {
                byte[] receiveBytes = Udp_Client.Receive(ref IP_EP); // 接收消息，得到数据报
                string returnData = Encoding.UTF8.GetString(receiveBytes);     // 解析字节数组，得到原消息
                Invoke((EventHandler)(delegate
                {
                    textbox_Receive.AppendText(returnData);
                }));
            }
        }
        private void ClientConnect(string ip, string port)
        {
            try
            {
                Client = new TcpClient(ip, int.Parse(port));
                ThreadStart threadStart = new ThreadStart(ClientAcceptMsg);
                Td_Client = new Thread(threadStart);
                Td_Client.Start();
                Tips.Text = "连接成功";
            }
            catch (Exception ex)
            {
                Tips.Text = "未连接";
                MessageBox.Show(ex.Message);
            }
        }
        NetworkStream ns;
        private void ClientAcceptMsg()
        {
            ns = Client.GetStream();
            while (true)
            {
                try
                {
                    byte[] bytes = new byte[1024];
                    int bytesread = ns.Read(bytes, 0, bytes.Length);
                    string msg = Encoding.Default.GetString(bytes, 0, bytesread);
                    textbox_Receive.AppendText(msg);
                    ns.Flush();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
        private void SeriverConnect(string ip, string port)
        {
            try
            {
                Td_Listen = new Thread(StartListen);
                listener = new TcpListener(IPAddress.Parse(ip), int.Parse(port));
                if (m_bListening)
                {
                    m_bListening = false;
                }
                else
                {
                    m_bListening = true;
                    Td_Listen.Start();
                }
                Tips.Text = "连接成功";
            }
            catch (Exception ex)
            {
                Tips.Text = "未连接";
                MessageBox.Show(ex.Message);
            }
        }

        private void StartListen()
        {
            listener.Start();
            while (m_bListening)
            {
                try
                {
                    TcpClient client = listener.AcceptTcpClient();
                    clientArray.Add(client);
                    ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SeriverAcceptMsg);
                    Td_Seriver = new Thread(threadStart);
                    Td_Seriver.Start(client);
                }
                catch (Exception re)
                {
                    MessageBox.Show(re.Message);
                }
            }
            listener.Stop();
        }
        private void SeriverAcceptMsg(object arg)
        {
            TcpClient client = (TcpClient)arg;
            NetworkStream ns = client.GetStream();
            while (true)
            {
                try
                {
                    byte[] bytes = new byte[1024];
                    int bytesread = ns.Read(bytes, 0, bytes.Length);
                    string msg = Encoding.Default.GetString(bytes, 0, bytesread);
                    textbox_Receive.AppendText(msg);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
        ArrayList clientArray = new ArrayList();
        private void btn_Send_Click(object sender, EventArgs e)
        {
            if (Mode == 1)
            {
                string msg = textbox_Send.Text;
                byte[] sendBytes = Encoding.UTF8.GetBytes(msg);
                Udp_Client.Send(sendBytes, sendBytes.Length);
            }
            if (Mode == 2)
            {
                if (Client == null)
                    return;
                NetworkStream SendStream = Client.GetStream();
                string msg = textbox_Send.Text;
                byte[] sendBytes = Encoding.Default.GetBytes(msg);
                SendStream.Write(sendBytes, 0, sendBytes.Length);
                SendStream.Flush();
            }
            if (Mode == 3)
            {
                TcpClient client = (TcpClient)clientArray[0];
                if (client == null)
                    return;
                NetworkStream sendStream = client.GetStream();
                string msg = textbox_Send.Text;
                byte[] sendBytes = Encoding.Default.GetBytes(msg);
                sendStream.Write(sendBytes, 0, sendBytes.Length);
                sendStream.Flush();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(0);
        }
    }
}
